package com.activity;

import com.misc.Tool;
import com.type.ByteArrayParcelable;
import com.type.Comment;
import com.type.Subscriber;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.SimpleAdapter.ViewBinder;
import android.widget.Toast;
import android.widget.ToggleButton;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class UserTopicDetailActivity extends Activity {
	ListView cmtListView;
	GridView sbcbGridView;
	ToggleButton tglBtnSbcb;
	Button  btnAddCmt,  btnPhotoCmt;
	
	ArrayList<Comment> cmtList;
	ArrayList<Subscriber> sbcbList;
	
	String creatorPhNum;
	String title;
	String textCmt;
	Bitmap photoCmt;
	
	String myPhNum;
	String myName; 
	byte[] myAvatar;
	
	static Socket socket;
	static DataOutputStream dos;
	static DataInputStream dis;
	
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.frd_topic_detail);

		creatorPhNum = getIntent().getStringExtra(ViewMyCreatedTopicActivity.CREATOR_PH_NUM);
		title = getIntent().getStringExtra(FrdTopicActivity.TITLE);
		myPhNum = getIntent().getStringExtra(MainActivity.MY_PH_NUM);
		myName = getIntent().getStringExtra(MainActivity.MY_NAME);
		myAvatar = ((ByteArrayParcelable) getIntent().getParcelableExtra(MainActivity.MY_AVATAR)).getByteArray();
		
		cmtListView = (ListView) findViewById(R.id.comment_list_view);
		sbcbGridView = (GridView) findViewById(R.id.subscriber_grid_view);
		
		tglBtnSbcb = (ToggleButton)findViewById(R.id.toggle_btn_subscribe);
		tglBtnSbcb.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				if(tglBtnSbcb.isChecked()) 
					(new SbcbTopicTask(UserTopicDetailActivity.this)).execute(
																					MainActivity.SERVER_IP, 
																					MainActivity.PORT, 
																					creatorPhNum,
																					title,
																					myPhNum);
				else 
					(new UnsbcbTopicTask(UserTopicDetailActivity.this)).execute(
																					MainActivity.SERVER_IP, 
																					MainActivity.PORT, 
																					creatorPhNum,
																					title, 
																					myPhNum);
			}
		});

		btnAddCmt = (Button)findViewById(R.id.btn_add_comment);
		btnAddCmt.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				showAddCmtDialog();
			}
		});

		if(getIntent().hasExtra(ViewMyCreatedTopicActivity.ALWAYS_HIDE_SBCB_BUTTON_AND_NOT_HIDE_CMT_BUTTON)) { 
			tglBtnSbcb.setVisibility(View.INVISIBLE);
			btnAddCmt.setVisibility(View.VISIBLE);
		}
		
		photoCmt = BitmapFactory.decodeResource(getResources(), R.drawable.photo_comment_default);

		(new FetchCmtAndSbcbTask(this))
		.execute(
		    MainActivity.SERVER_IP, 
		    MainActivity.PORT, 
		    creatorPhNum, 
		    title, 
		    myPhNum);
	}
	
	
	void showAddCmtDialog() {
		final View dialogView = LayoutInflater.from(this).inflate(R.layout.add_cmt_dialog, null);
		btnPhotoCmt = (Button) dialogView.findViewById(R.id.ibPhotoComment);
		btnPhotoCmt.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
				intent.setType("image/*");
				intent.putExtra("return-data", true);
				startActivityForResult(intent, 0);
			}
		});
		
		(new AlertDialog.Builder(this).setView(dialogView)
				.setPositiveButton("OK", new DialogInterface.OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog, int whichButton) {
						textCmt = ((EditText) dialogView.findViewById(R.id.etTextComment)).getText().toString();
						if (textCmt == null || textCmt.length() == 0)
							Toast.makeText(UserTopicDetailActivity.this, "empty text, please write some text comment", Toast.LENGTH_LONG).show();
						else {
							(new AddCmtTask(UserTopicDetailActivity.this)).execute(new ParamForAddCmtTask(
																								MainActivity.SERVER_IP, 
																								Integer.parseInt(MainActivity.PORT), 
																								creatorPhNum,
																								title,
																								myPhNum,
																								textCmt, 
																								Tool.bitmap2ByteArray(photoCmt)));
							dialog.dismiss();
						}
					}
				}).setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog, int which) {
						dialog.dismiss();
					}
				})).create().show();
	}
	
	
	protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
		if (requestCode == 0 && intent != null) {
			photoCmt = intent.getParcelableExtra("data");
			Matrix matrix = new Matrix();
			matrix.postScale(130 / (float) photoCmt.getWidth(), 100 / (float) photoCmt.getHeight());
			btnPhotoCmt.setBackgroundDrawable(new BitmapDrawable(Bitmap.createBitmap(photoCmt, 0, 0, photoCmt.getWidth(), photoCmt.getHeight(), matrix, true)));
			btnPhotoCmt.setHint("");
		}
	}
	

	void refreshCmtListView() {
		if(cmtList.isEmpty())
			Toast.makeText(this, "till now no person have commented to this topic", Toast.LENGTH_LONG).show();

		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		for(Comment cmt : cmtList) {
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("commenter_avatar", Tool.byteArray2Bitmap(cmt.getAvatar()));
			map.put("commenter_name", cmt.getName());
			map.put("text_comment", cmt.getTextCmt());
			map.put("photo_comment", Tool.byteArray2Bitmap(cmt.getPhotoCmt()));
			list.add(map);
		}
		SimpleAdapter adapter = new SimpleAdapter(
										this, 
										list,
										R.layout.cmt_list_item, 
										new String[]{"commenter_avatar", "commenter_name", "text_comment", "photo_comment"}, 
										new int[]{R.id.ivCommenterAvatar, R.id.tvCommenterName, R.id.tvTextComment, R.id.ivPhotoComment});
		adapter.setViewBinder(new ViewBinder() {
			@Override
			public boolean setViewValue(View view, Object data, String textRepresentation) {
				if(data == null)
					return false;
				else if ((view instanceof ImageView) & (data instanceof Bitmap)) {
					ImageView iv = (ImageView) view;
					Bitmap bm = (Bitmap) data;
					iv.setImageBitmap(bm);
					return true;
				} else
					return false;
			}
		});
		cmtListView.setAdapter(adapter);
	}
	
	
	void refreshSbcbGridView() {
		if(sbcbList.isEmpty())
			Toast.makeText(this, "till now no person have subscribed this topic", Toast.LENGTH_LONG).show();

		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		for(Subscriber sbcb : sbcbList) {
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("sbcb_photo", Tool.byteArray2Bitmap(sbcb.getAvatar()));
			map.put("sbcb_name", sbcb.getName());
			list.add(map);
		}
		SimpleAdapter adapter = new SimpleAdapter(
										this, 
										list,
										R.layout.sbcb_grid_view_item, 
										new String[]{"sbcb_photo", "sbcb_name"}, 
										new int[]{R.id.ivSbcbPhoto, R.id.tvSbcbName});
		sbcbGridView.setAdapter(adapter);
		adapter.setViewBinder(new ViewBinder() {
			@Override
			public boolean setViewValue(View view, Object data, String textRepresentation) {
				if ((view instanceof ImageView) && (data instanceof Bitmap)) {
					ImageView iv = (ImageView) view;
					Bitmap bitmap = (Bitmap) data;
					iv.setImageBitmap(bitmap);
					return true;
				} else
					return false;
			}
		});
	}


	class ResultForFetchCmtAndSbcbTask {
		ArrayList<Comment> cmtList;
		ArrayList<Subscriber> sbcbList;
		boolean isJoined;
		public ResultForFetchCmtAndSbcbTask(ArrayList<Comment> cmtList, ArrayList<Subscriber> sbcbList, boolean isJoined) {
			this.cmtList = cmtList;
			this.sbcbList = sbcbList;
			this.isJoined = isJoined;
		}
		public ArrayList<Comment> getCmtList() {
			return cmtList;
		}
		public ArrayList<Subscriber> getSbcbList() {
			return sbcbList;
		}
		public boolean getIsJoined() {
			return isJoined;
		}
	}
	class FetchCmtAndSbcbTask extends AsyncTask<String, Void, ResultForFetchCmtAndSbcbTask> {
	    UserTopicDetailActivity friendTopicDetailActivity;
	
	    public FetchCmtAndSbcbTask(UserTopicDetailActivity friendTopicDetailActivity) {
	        this.friendTopicDetailActivity = friendTopicDetailActivity;
	    }
	
	    @Override
		protected ResultForFetchCmtAndSbcbTask doInBackground(String... params) {
	    	ResultForFetchCmtAndSbcbTask result = null;
	    	try {
				socket = new Socket(params[0], Integer.parseInt(params[1]));
				dos = new DataOutputStream(socket.getOutputStream());
				dis = new DataInputStream(socket.getInputStream());
				dos.writeInt(FrdTopicDetailActivity.FETCH_COMMENT_AND_SUBSCRIBE);
				
				dos.writeUTF(params[2]);	// topic creator's phone number
				dos.writeUTF(params[3]);	// title
				
				ArrayList<Comment> cmtList = new ArrayList<Comment>();
				int cmtCount = dis.readInt();
				if(cmtCount > 0) {
					for(int i=0; i < cmtCount; i++) {
						byte[] avatar = Tool.receiveByteArray(dis);
						String name = dis.readUTF();
						String phNum = dis.readUTF();
						String textCmt = dis.readUTF();
						byte[] photoCmt = Tool.receiveByteArray(dis);
						Comment cmt = new Comment(avatar, name, phNum, textCmt, photoCmt);
						cmtList.add(cmt);
					}
				}
				
				ArrayList<Subscriber> sbcbList = new ArrayList<Subscriber>();
				int sbcbCount = dis.readInt();
				if(sbcbCount > 0) {
					for(int i=0; i < sbcbCount; i++) {
						byte[] avatar = Tool.receiveByteArray(dis);
						String name = dis.readUTF();
						String phNum = dis.readUTF();
						Subscriber sbcb = new Subscriber(avatar, name, phNum);
						sbcbList.add(sbcb);
					}
				}
				
				dos.writeUTF(params[4]);	// my phone number
				boolean isJoined = dis.readBoolean();

				result = new ResultForFetchCmtAndSbcbTask(cmtList, sbcbList, isJoined);
	    	} catch (Exception e) {
				e.printStackTrace();
			} finally {
				try {
					dis.close();
					dos.close();
					socket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			return result;
		}

		@Override
		protected void onPostExecute(ResultForFetchCmtAndSbcbTask result) {
			friendTopicDetailActivity.onFetchCmtAndSbcbTaskComplete(result.getCmtList(), result.getSbcbList(), result.getIsJoined());
		}
	}

	
	public void onFetchCmtAndSbcbTaskComplete(ArrayList<Comment> cmtList, ArrayList<Subscriber> sbcbList, boolean isJoined) {
		tglBtnSbcb.setChecked(isJoined);
		if(!getIntent().hasExtra(ViewMyCreatedTopicActivity.ALWAYS_HIDE_SBCB_BUTTON_AND_NOT_HIDE_CMT_BUTTON))  
			btnAddCmt.setVisibility(isJoined ? View.VISIBLE : View.INVISIBLE);
		this.cmtList = cmtList;
		this.sbcbList = sbcbList;
		refreshSbcbGridView();
		refreshCmtListView();
	}


	class SbcbTopicTask extends AsyncTask<String, Void, Void> {
	    UserTopicDetailActivity friendTopicDetailActivity;
	
	    public SbcbTopicTask(UserTopicDetailActivity friendTopicDetailActivity) {
	        this.friendTopicDetailActivity = friendTopicDetailActivity;
	    }
	
	    @Override
		protected Void doInBackground(String... params) {
			try {
				socket = new Socket(params[0], Integer.parseInt(params[1]));
				dos = new DataOutputStream(socket.getOutputStream());
				dos.writeInt(FrdTopicDetailActivity.SEND_SUBSCRIBE_TOPIC);

				dos.writeUTF(params[2]);	// friend's phone number
				dos.writeUTF(params[3]);	// title
				dos.writeUTF(params[4]);	// my phone number
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				try {
					dos.close();
					socket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			return null;
		}

		@Override
		protected void onPostExecute(Void result) {
			friendTopicDetailActivity.onSbcbTopicTaskComplete();
		}
	}

	
	public void onSbcbTopicTaskComplete() {
		sbcbList.add(new Subscriber(myAvatar, myName, myPhNum));
		refreshSbcbGridView();
		btnAddCmt.setVisibility(View.VISIBLE);
	}
	
	
	class UnsbcbTopicTask extends AsyncTask<String, Void, Void> {
	    UserTopicDetailActivity friendTopicDetailActivity;
	
	    public UnsbcbTopicTask(UserTopicDetailActivity friendTopicDetailActivity) {
	        this.friendTopicDetailActivity = friendTopicDetailActivity;
	    }
	
	    @Override
		protected Void doInBackground(String... params) {
	    	try {
				socket = new Socket(params[0], Integer.parseInt(params[1]));
				dos = new DataOutputStream(socket.getOutputStream());
				dos.writeInt(FrdTopicDetailActivity.SEND_UNSUBSCRIBE_TOPIC);

				dos.writeUTF(params[2]);	// friend's phone number
				dos.writeUTF(params[3]);	// title
				dos.writeUTF(params[4]);	// my phone number
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				try {
					dos.close();
					socket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			return null;
		}

		@Override
		protected void onPostExecute(Void result) {
			friendTopicDetailActivity.onUnsbcbTopicTaskComplete();
		}
	}
	
	
	public void onUnsbcbTopicTaskComplete() {
		ArrayList<Subscriber> tempSbcbList = new ArrayList<Subscriber>();
		for(Subscriber sbcb : sbcbList) 
			if(! sbcb.getPhNum().equals(myPhNum))
				tempSbcbList.add(sbcb);
		sbcbList = tempSbcbList;
		refreshSbcbGridView();
		btnAddCmt.setVisibility(View.INVISIBLE);
	}

	
	class ParamForAddCmtTask {
		String serverIp;
		int port;
		String frdPhNum;
		String title;
		String myPhNum;
		String textCmt;
		byte[] photoCmt;
		public ParamForAddCmtTask(String serverIp, int port, String frdPhNum, String title, String myPhNum, String textCmt, byte[] photoCmt) {
			super();
			this.serverIp = serverIp;
			this.port = port;
			this.frdPhNum = frdPhNum;
			this.title = title;
			this.myPhNum = myPhNum;
			this.textCmt = textCmt;
			this.photoCmt = photoCmt;
		}
		public String getServerIp() {
			return serverIp;
		}
		public int getPort() {
			return port;
		}
		public String getFrdPhNum() {
			return frdPhNum;
		}
		public String getTitle() {
			return title;
		}
		public String getMyPhNum() {
			return myPhNum;
		}
		public String getTextCmt() {
			return textCmt;
		}
		public byte[] getPhotoCmt() {
			return photoCmt;
		}
	}
	class AddCmtTask extends AsyncTask<ParamForAddCmtTask, Void, Void> {
	    UserTopicDetailActivity friendTopicDetailActivity;
	
	    public AddCmtTask(UserTopicDetailActivity friendTopicDetailActivity) {
	        this.friendTopicDetailActivity = friendTopicDetailActivity;
	    }
	
	    @Override
		protected Void doInBackground(ParamForAddCmtTask... params) {
	    	try {
				socket = new Socket(params[0].getServerIp(), params[0].getPort());
				dos = new DataOutputStream(socket.getOutputStream());
				dos.writeInt(FrdTopicDetailActivity.SEND_ADD_COMMENT);

				dos.writeUTF(params[0].getFrdPhNum());
				dos.writeUTF(params[0].getTitle());
				dos.writeUTF(params[0].getMyPhNum());
				dos.writeUTF(params[0].getTextCmt());
				Tool.sendByteArray(dos, params[0].getPhotoCmt());
			} catch (IOException e) {
				e.printStackTrace();
			} catch (InterruptedException e) {
				e.printStackTrace();
			} finally {
				try {
					dos.close();
					socket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			return null;
		}

		@Override
		protected void onPostExecute(Void result) {
			friendTopicDetailActivity.onAddCmtTaskComplete();
		}
	}	
	
	
	public void onAddCmtTaskComplete() {
		cmtList.add(new Comment(myAvatar, myName, myPhNum, textCmt, Tool.bitmap2ByteArray(photoCmt)));
		refreshCmtListView();
	}
}
